package com.ruoyi.imports.service.impl;

import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.imports.domain.TdRawWater;
import com.ruoyi.imports.domain.TdRawWaterType;
import com.ruoyi.imports.domain.RawWaterExcelData;
import com.ruoyi.imports.mapper.TdRawWaterMapper;
import com.ruoyi.imports.mapper.TdRawWaterTypeMapper;
import com.ruoyi.imports.service.ITdRawWaterTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 原料水检测分类Service业务层处理
 *
 * @author ruoyi
 * @date 2025-07-14
 */
@Service
public class TdRawWaterTypeServiceImpl implements ITdRawWaterTypeService {
    // 日期格式化工具（仅处理日期部分）
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy年M月d日", Locale.CHINESE);

    static {
        DATE_FORMAT.setLenient(false); // 严格校验日期格式
    }


    @Autowired
    private TdRawWaterTypeMapper tdRawWaterTypeMapper;

    @Autowired
    private TdRawWaterMapper tdRawWaterMapper;

    /**
     * 查询原料水检测分类
     *
     * @param id 原料水检测分类主键
     * @return 原料水检测分类
     */
    @Override
    public TdRawWaterType selectTdRawWaterTypeById(Long id) {
        return tdRawWaterTypeMapper.selectTdRawWaterTypeById(id);
    }

    /**
     * 查询原料水检测分类列表
     *
     * @param tdRawWaterType 原料水检测分类
     * @return 原料水检测分类
     */
    @Override
    public List<TdRawWaterType> selectTdRawWaterTypeList(TdRawWaterType tdRawWaterType) {
        return tdRawWaterTypeMapper.selectTdRawWaterTypeList(tdRawWaterType);
    }

    /**
     * 新增原料水检测分类
     *
     * @param tdRawWaterType 原料水检测分类
     * @return 结果
     */
    @Override
    public int insertTdRawWaterType(TdRawWaterType tdRawWaterType) {
        tdRawWaterType.setCreateTime(DateUtils.getNowDate());
        return tdRawWaterTypeMapper.insertTdRawWaterType(tdRawWaterType);
    }

    /**
     * 修改原料水检测分类
     *
     * @param tdRawWaterType 原料水检测分类
     * @return 结果
     */
    @Override
    public int updateTdRawWaterType(TdRawWaterType tdRawWaterType) {
        tdRawWaterType.setUpdateTime(DateUtils.getNowDate());
        return tdRawWaterTypeMapper.updateTdRawWaterType(tdRawWaterType);
    }

    /**
     * 批量删除原料水检测分类
     *
     * @param ids 需要删除的原料水检测分类主键
     * @return 结果
     */
    @Override
    public int deleteTdRawWaterTypeByIds(Long[] ids) {
        return tdRawWaterTypeMapper.deleteTdRawWaterTypeByIds(ids);
    }

    /**
     * 删除原料水检测分类信息
     *
     * @param id 原料水检测分类主键
     * @return 结果
     */
    @Override
    public int deleteTdRawWaterTypeById(Long id) {
        return tdRawWaterTypeMapper.deleteTdRawWaterTypeById(id);
    }

    /**
     * 导入原料水检测数据（主逻辑）
     */
    @Transactional(rollbackFor = Exception.class)
    public void importRawWaterType(List<RawWaterExcelData> excelDataList, Long projectId) {
        // 1. 基础校验
        if (excelDataList == null || excelDataList.isEmpty()) {
            throw new IllegalArgumentException("导入数据不能为空");
        }

        // 2. 日期连续性校验（核心逻辑）
        validateDateContinuity(excelDataList);


        // 存储Excel行索引与主表ID的映射（用于关联子表）
        Map<Integer, Long> rowToMainIdMap = new HashMap<>(excelDataList.size());

        try {
            // 2. 处理主表数据（td_raw_water）
            for (int i = 0; i < excelDataList.size(); i++) {
                RawWaterExcelData excelData = excelDataList.get(i);
                // 构建主表实体并插入
                TdRawWater mainData = buildMainData(excelData, projectId);
                tdRawWaterMapper.insertTdRawWater(mainData);
                // 记录映射关系
                rowToMainIdMap.put(i, mainData.getId());
            }

            // 3. 处理子表数据（td_raw_water_type）
            List<TdRawWaterType> typeDataList = new ArrayList<>();
            for (int i = 0; i < excelDataList.size(); i++) {
                RawWaterExcelData excelData = excelDataList.get(i);
                Long mainId = rowToMainIdMap.get(i);
                // 按类型添加子表数据（蒸氨废水/剩余氨水/其他配水）
                typeDataList.add(buildTypeData(excelData, mainId, "蒸氨废水"));
                typeDataList.add(buildTypeData(excelData, mainId, "剩余氨水"));
                typeDataList.add(buildTypeData(excelData, mainId, "其他配水"));
            }
            // 批量插入子表
            if (!typeDataList.isEmpty()) {
                tdRawWaterTypeMapper.batchInsert(typeDataList);
            }

        } catch (Exception e) {
            // 异常捕获与日志
            throw new RuntimeException("导入失败：" + e.getMessage(), e);
        }
    }

    /**
     * 校验日期是否连续（按自然日顺序，不允许跳日）
     */
    private void validateDateContinuity(List<RawWaterExcelData> dataList) {
        try {
            // 提取并解析所有日期
            List<Date> dateList = new ArrayList<>(dataList.size());
            for (RawWaterExcelData data : dataList) {
                String dateStr = data.getDate();
                if (dateStr == null || dateStr.trim().isEmpty()) {
                    throw new IllegalArgumentException("第" + (dateList.size() + 1) + "行：日期不能为空");
                }
                // 解析日期字符串为Date（仅保留日期部分）
                Date date = DATE_FORMAT.parse(dateStr.trim());
                dateList.add(date);
            }

            // 校验连续日期
            for (int i = 1; i < dateList.size(); i++) {
                Date prevDate = dateList.get(i - 1);
                Date currDate = dateList.get(i);

                // 计算前一天日期
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(prevDate);
                calendar.add(Calendar.DAY_OF_YEAR, 1);
                Date expectedNextDate = calendar.getTime();

                // 比较当前日期是否为前一天的次日
                if (!currDate.equals(expectedNextDate)) {
                    // 格式化错误信息中的日期
                    String prevDateStr = DATE_FORMAT.format(prevDate);
                    String currDateStr = DATE_FORMAT.format(currDate);
                    throw new RuntimeException(
                            String.format("日期不连续：第%d行日期为%s，第%d行日期为%s（应为%s的次日）",
                                    i, prevDateStr, i + 1, currDateStr, prevDateStr)
                    );
                }
            }
        } catch (ParseException e) {
            throw new RuntimeException("日期格式错误：" + e.getMessage(), e);
        }
    }


    /**
     * 构建主表数据（核心：日期时间解析）
     */
    private TdRawWater buildMainData(RawWaterExcelData excelData, Long projectId) throws ParseException {
        TdRawWater mainData = new TdRawWater();
        mainData.setProjectId(projectId);

        // 校验日期和时间非空
        String dateStr = excelData.getDate();
        String timeStr = excelData.getTime();
        if (dateStr == null || timeStr == null) {
            throw new IllegalArgumentException("日期或时间不能为空");
        }

        // 合并日期时间字符串（格式：yyyy年M月d日 HH:mm）
        String dateTimeStr = dateStr.trim() + " " + timeStr.trim();

        // 解析为Date（仅保留必要格式，适配Excel实际格式）
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年M月d日 HH:mm", Locale.CHINESE);
        sdf.setLenient(false); // 严格校验格式
        Date recordTime = sdf.parse(dateTimeStr);
        mainData.setRecordTime(recordTime);

        // 设置创建/更新信息（按实际实体类字段调整）
        mainData.setCreateTime(new Date());
        mainData.setUpdateTime(new Date());
        mainData.setCreateBy(SecurityUtils.getUsername());
        mainData.setUpdateBy(SecurityUtils.getUsername());

        return mainData;
    }

    /**
     * 构建子表数据（按类型映射指标）
     */
    private TdRawWaterType buildTypeData(RawWaterExcelData excelData, Long mainId, String type) {
        TdRawWaterType typeData = new TdRawWaterType();
        typeData.setRawWaterId(mainId); // 关联主表ID
        typeData.setType(type);

        // 设置通用字段
        Long userId = SecurityUtils.getUserId();
        typeData.setCreateUser(userId);
        typeData.setUpdateUser(userId);
        typeData.setCreateTime(new Date());
        typeData.setUpdateTime(new Date());
        typeData.setIsDeleted(0);

        // 按类型映射所有指标（根据数据库记录补全）
        if ("蒸氨废水".equals(type)) {
            typeData.setPh(parseBigDecimal(excelData.getZhengAnPh()));
            typeData.setSs(parseBigDecimal(excelData.getZhengAnSs()));
            typeData.setNh3n(parseBigDecimal(excelData.getZhengAnNh3N()));
            typeData.setTn(parseBigDecimal(excelData.getZhengAnTn()));
            typeData.setCod(parseBigDecimal(excelData.getZhengAnCod()));
            typeData.setBod(parseBigDecimal(excelData.getZhengAnBod()));
            typeData.setThiocyanate(parseBigDecimal(excelData.getZhengAnThiocyanate()));
            typeData.setSulfide(parseBigDecimal(excelData.getZhengAnSulfide()));
            typeData.setVolatilePhenols(parseBigDecimal(excelData.getZhengAnVolatilePhenols()));
            typeData.setAlk(parseBigDecimal(excelData.getZhengAnAlk()));
            typeData.setCi(parseBigDecimal(excelData.getZhengAnCi()));
            typeData.setPetroleum(parseBigDecimal(excelData.getZhengAnPetroleum()));
            typeData.setBenzene(parseBigDecimal(excelData.getZhengAnBenzene()));
            typeData.setPah(parseBigDecimal(excelData.getZhengAnPah()));
            typeData.setBap(parseBigDecimal(excelData.getZhengAnBap()));
            typeData.setTc(parseBigDecimal(excelData.getZhengAnTc()));
        } else if ("剩余氨水".equals(type)) {
            typeData.setPh(parseBigDecimal(excelData.getShengYuPh()));
            typeData.setSs(parseBigDecimal(excelData.getShengYuSs()));
            typeData.setNh3n(parseBigDecimal(excelData.getShengYuNh3N()));
            typeData.setTn(parseBigDecimal(excelData.getShengYuTn()));
            typeData.setCod(parseBigDecimal(excelData.getShengYuCod()));
            typeData.setBod(parseBigDecimal(excelData.getShengYuBod()));
            typeData.setThiocyanate(parseBigDecimal(excelData.getShengYuThiocyanate()));
            typeData.setSulfide(parseBigDecimal(excelData.getShengYuSulfide()));
            typeData.setVolatilePhenols(parseBigDecimal(excelData.getShengYuVolatilePhenols()));
            typeData.setAlk(parseBigDecimal(excelData.getShengYuAlk()));
            typeData.setCi(parseBigDecimal(excelData.getShengYuCi()));
            typeData.setPetroleum(parseBigDecimal(excelData.getShengYuPetroleum()));
            typeData.setBenzene(parseBigDecimal(excelData.getShengYuBenzene()));
            typeData.setPah(parseBigDecimal(excelData.getShengYuPah()));
            typeData.setBap(parseBigDecimal(excelData.getShengYuBap()));
            typeData.setTc(parseBigDecimal(excelData.getShengYuTc()));
        } else if ("其他配水".equals(type)) {
            typeData.setPh(parseBigDecimal(excelData.getQiTaPh()));
            typeData.setSs(parseBigDecimal(excelData.getQiTaSs()));
            typeData.setNh3n(parseBigDecimal(excelData.getQiTaNh3N()));
            typeData.setTn(parseBigDecimal(excelData.getQiTaTn()));
            typeData.setCod(parseBigDecimal(excelData.getQiTaCod()));
            typeData.setBod(parseBigDecimal(excelData.getQiTaBod()));
            typeData.setThiocyanate(parseBigDecimal(excelData.getQiTaThiocyanate()));
            typeData.setSulfide(parseBigDecimal(excelData.getQiTaSulfide()));
            typeData.setVolatilePhenols(parseBigDecimal(excelData.getQiTaVolatilePhenols()));
            typeData.setAlk(parseBigDecimal(excelData.getQiTaAlk()));
            typeData.setCi(parseBigDecimal(excelData.getQiTaCi()));
            typeData.setPetroleum(parseBigDecimal(excelData.getQiTaPetroleum()));
            typeData.setBenzene(parseBigDecimal(excelData.getQiTaBenzene()));
            typeData.setPah(parseBigDecimal(excelData.getQiTaPah()));
            typeData.setBap(parseBigDecimal(excelData.getQiTaBap()));
            typeData.setTc(parseBigDecimal(excelData.getQiTaTc()));
        }

        return typeData;
    }

    /**
     * 字符串转BigDecimal（工具方法）
     */
    private BigDecimal parseBigDecimal(String value) {
        if (value == null || value.trim().isEmpty() || "-".equals(value.trim())) {
            return null;
        }
        try {
            return new BigDecimal(value.trim());
        } catch (NumberFormatException e) {
            System.err.println("数值格式错误: " + value);
            return null;
        }
    }
}

